package coop.bancocredicoop.proyectos.gd.reports;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Criteria;
import org.hibernate.classic.Session;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import coop.bancocredicoop.proyectos.gd.domain.Document;

public class VersionsByFileReport {

	public DocumentVersions versionsByFile(Session session, Long idPersona, String cajaId, Date dateFrom, Date dateTo, int offset, int limit) {
		
		Criteria criteria = session.createCriteria(Document.class);
		
		Criteria countCriteria = session.createCriteria(Document.class)
				.createAlias("customer", "asociado")
				.createAlias("documentType", "docType")
				.createAlias("box", "box");				
		countCriteria = addConditions(countCriteria, idPersona, cajaId, dateFrom, dateTo);
		
		Integer totalCount = ((Number) countCriteria.setProjection(Projections.rowCount()).uniqueResult()).intValue();
		
		criteria = criteria
					.setFirstResult(offset)
					.setMaxResults(limit)
					.createAlias("customer", "asociado")
					.createAlias("documentType", "docType")
					.createAlias("box", "box")					
    				.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP)
    				.addOrder(Order.asc("asociado.idPersona"))
    				.addOrder(Order.asc("docType.name"));
		
		criteria = addConditions(criteria, idPersona, cajaId, dateFrom, dateTo);
    				
		
	    List<Map<String, Object>> rows = criteria.list();
	    List<Map<String, Object>> items = new ArrayList<Map<String,Object>>();
	    
	    for (Map<String, Object> row : rows) {
	    	Map<String, Object> item = new HashMap<String, Object>();
	    	item.put("document", row.get("this"));
	    	items.add(item);
	    }

		DocumentVersions documentVersions = new DocumentVersions(items, totalCount, offset);
		return documentVersions;
		
	}
	
	private Criteria addConditions(Criteria criteria, Long idPersona, String cajaId, Date dateFrom, Date dateTo) {
		criteria = criteria.add(Restrictions.isNull("deleteDate"));
		if (idPersona != null) {
			criteria = criteria.add(Restrictions.eq("asociado.idPersona", idPersona));
		}
			
		if (cajaId != null) {
			criteria = criteria.add(Restrictions.eq("box.cajaId", cajaId));
		}
		
		if (dateFrom != null) {
			criteria = criteria.add(Restrictions.gt("createdDate", dateFrom));
		}
		
		if (dateTo != null) {
			criteria = criteria.add(Restrictions.le("createdDate", dateTo));
		}
		return criteria;
	}
	
}
